/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.antlr; import antlr.*; import org.openide.nodes.*; /** * <b>SOFTWARE RIGHTS</b> * <p> * ANTLR 2.6.0 MageLang Institute * <p> * We reserve no legal rights to the ANTLR--it is fully in the * public domain. An individual or company may do whatever * they wish with source code distributed with ANTLR or the * code generated by ANTLR, including the incorporation of * ANTLR, or its output, into commerical software. * <p> * We encourage users to develop software with ANTLR. However, * we do ask that credit is given to us for developing * ANTLR. By "credit", we mean that if you use ANTLR or * incorporate any source code into one of your programs * (commercial product, research project, or otherwise) that * you acknowledge this fact somewhere in the documentation, * research report, etc... If you like ANTLR and have * developed a nice tool with the output, please mention that * you developed it using ANTLR. In addition, we ask that the * headers remain intact in our source code. As long as these * guidelines are kept, we expect to continue enhancing this * system and expect to make other tools available as they are * completed. * <p> * The ANTLR gang: * @version ANTLR 2.6.0 MageLang Institute * @author Terence Parr, <a href=http://www.MageLang.com>MageLang Institute</a> * @author <br>John Lilley, <a href=http://www.Empathy.com>Empathy Software</a> */ import java.io.*; import antlr.collections.impl.BitSet; import antlr.collections.impl.Vector; public class Tool extends antlr.Tool { public static final String version = "2.6.0"; // Object that handles analysis errors ToolErrorHandler errorHandler; // Was there an error during parsing or analysis? protected boolean hasError = false; // Generate diagnostics? (vs code) boolean genDiagnostics = false; /** Generate HTML vs code? */ boolean genHTML = false; /** Current output directory for generated files */ protected static String outputDir = "."; // Grammar input String grammarFile; transient Reader f = new InputStreamReader(System.in); // SAS: changed for proper text io // transient DataInputStream in = null; protected static String literalsPrefix = "LITERAL_"; protected static boolean upperCaseMangledLiterals = false; private static BitSet cmdLineArgValid = new BitSet(); /** Construct a new Tool. */ public Tool() { // SAS: removed private so could create subclass errorHandler = new antlr.DefaultToolErrorHandler(); } private static void checkForInvalidArguments(String[] args, BitSet cmdLineArgValid) { // check for invalid command line args for (int a = 0; a < args.length; a++) { if (!cmdLineArgValid.member(a)) { warning("invalid command-line argument: " + args[a] + "; ignored"); } } } /** Perform processing on the grammar file. Can only be called from main() * @param args The command-line arguments passed to main() */ protected void doEverything(String[] args) { // SAS: removed "private" so subclass can call // (The subclass is for the VAJ interface) // run the preprocessor to handle inheritance first. antlr.preprocessor.Tool preTool = new antlr.preprocessor.Tool(this, args); if ( !preTool.preprocess() ) { inform("Preprocessor failed!"); return; } String[] modifiedArgs = preTool.preprocessedArgList(); // process arguments for the Tool processArguments(modifiedArgs); try { if (grammarFile != null) { f = new FileReader(grammarFile); } } catch (IOException e) { inform("Error: cannot open grammar file " + grammarFile); help(); return; } TokenBuffer tokenBuf = new TokenBuffer(new ANTLRLexer(f)); LLkAnalyzer analyzer = new LLkAnalyzer(this); MakeGrammar behavior = new MakeGrammar(this, args, analyzer); try { ANTLRParser p = new ANTLRParser(tokenBuf, behavior, this); p.setFilename(grammarFile); p.grammar(); if (hasError) { inform("Exiting due to errors."); return; } checkForInvalidArguments(modifiedArgs, cmdLineArgValid); // Create the right code generator according to the "language" option CodeGenerator codeGen; // SAS: created getLanguage() method so subclass can override // (necessary for VAJ interface) String codeGenClassName = "antlr." + getLanguage(behavior) + "CodeGenerator"; try { Class codeGenClass = Class.forName(codeGenClassName); codeGen = (CodeGenerator)codeGenClass.newInstance(); codeGen.setBehavior(behavior); codeGen.setAnalyzer(analyzer); codeGen.setTool(this); codeGen.gen(); } catch (ClassNotFoundException cnfe) { panic("Cannot instantiate code-generator: " + codeGenClassName); } catch (InstantiationException ie) { panic("Cannot instantiate code-generator: " + codeGenClassName); } catch (IllegalArgumentException ie) { panic("Cannot instantiate code-generator: " + codeGenClassName); } catch (IllegalAccessException iae) { panic("code-generator class '" + codeGenClassName + "' is not accessible"); } } catch (MismatchedTokenException mt) { inform("Unhandled parser error: " + mt.getMessage()); } catch (NoViableAltException nva) { inform("Unhandled parser error: " + nva.getMessage()); } catch (ParserException pe) { inform("Unhandled parser error: " + pe.getMessage()); } catch (IOException io) { inform("IOException: " + io.getMessage()); } } /** Issue an error * @param s The message */ public void error(String s) { hasError = true; inform("error: "+s); } /** Issue an error with line number information * @param s The message * @param file The file that has the error * @param line The grammar file line number on which the error occured */ public void error(String s, String file, int line) { hasError = true; if ( file!=null ) { inform("error in "+file+": line("+line+"), "+s); } else { inform("error; line "+line+": "+s); } } public static Object factory(String p) { Class c; Object o=null; try { c = Class.forName(p);// get class def o = c.newInstance(); // make a new one } catch (Exception e) { // either class not found, // class is interface/abstract, or // class or initializer is not accessible. warning("Can't create an object of type " + p); return null; } return o; } /** Determine the language used for this run of ANTLR * This was made a method so the subclass can override it */ public String getLanguage(MakeGrammar behavior) { if (genDiagnostics) { return "Diagnostic"; } if (genHTML) { return "HTML"; } return behavior.language; // "Java" } public static String getOutputDirectory() { return outputDir; } static private void help() { inform("HELP for ANTLR"); } public static void main(String[] args) { setRootNode("ANTLR Parser Generator Version "+ Tool.version+" 1989-1999 MageLang Institute"); org.openide.TopManager.getDefault().getNodeOperation().explore(rootNode); args = new String[] { "-o", "z:\\p\\antlr\\tst\\", "z:\\p\\antlr\\tst\\calc.g" }; try { if ( args.length==0 ) { help(); } Tool theTool = new Tool(); theTool.doEverything(args); theTool = null; } catch (Exception e) { System.err.println(System.getProperty("line.separator")+ System.getProperty("line.separator")); System.err.println("#$%%*&@# internal error: "+e.toString()); System.err.println("[complain to nearest government official"); System.err.println(" or send hate-mail to parrt@jguru.com;"); System.err.println(" please send stack trace with report.]"+ System.getProperty("line.separator")); e.printStackTrace(); } inform("ANTLR NetBeans module done compilation!!"); } public static PrintWriter openOutputFile(String f) throws IOException { return new PrintWriter(new FileWriter(outputDir+System.getProperty("file.separator")+f)); } /** Issue an unknown fatal error */ public static void panic() { inform("panic"); return;//System.exit(1); } /** Issue a fatal error message * @param s The message */ public static void panic(String s) { inform("panic: "+s); return;//System.exit(1); } /** Process the command-line arguments. Can only be called by Tool. * @param args The command-line arguments passed to main() */ private void processArguments(String[] args) { for (int i = 0; i < args.length; i++) { if (args[i].equals("-diagnostic")) { genDiagnostics = true; genHTML = false; Tool.setArgOK(i); } else { if (args[i].equals("-o")) { Tool.setArgOK(i); if (i + 1 >= args.length) { error("missing output directory with -o option; ignoring"); } else { i++; setOutputDirectory(args[i]); Tool.setArgOK(i); } } else if (args[i].equals("-html")) { genHTML = true; genDiagnostics = false; Tool.setArgOK(i); } else { if (args[i].charAt(0) != '-') { // Must be the grammar file grammarFile = args[i]; Tool.setArgOK(i); } } } } } public static void setArgOK(int i) { cmdLineArgValid.add(i); } public static void setOutputDirectory(String o) { outputDir = o; } static Node rootNode = null; static void setRootNode(String s) { rootNode = new AbstractNode(new Children.Array()); rootNode.setDisplayName(s); } static void inform(String s) { Node n = new AbstractNode(Children.LEAF); n.setDisplayName(s); rootNode.getChildren().add(new Node[]{ n }); } /** Issue an error; used for general tool errors not for grammar stuff * @param s The message */ public static void toolError(String s) { inform("error: "+s); } /** Issue a warning * @param s the message */ public static void warning(String s) { inform("warning: "+s); } /** Issue a warning with line number information * @param s The message * @param file The file that has the warning * @param line The grammar file line number on which the warning occured */ public static void warning(String s, String file, int line) { if ( file!=null ) { inform("warning in "+file+": line("+line+"), "+s); } else { inform("warning; line "+line+": "+s); } } }